package cn.imatu.framework.data.mate.fieldsensitive;

import cn.imatu.framework.data.mate.fieldsensitive.enums.StrategyType;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

/**
 * 脱敏策略配置
 * @author shenguangyang
 */
@Slf4j
public class SensitiveConfig {
    private static final SensitiveConfig instance = new SensitiveConfig();
    private final Map<String, Function<String, Object>> strategyMap = new ConcurrentHashMap<>();

    static {
        SensitiveConfig config = getInstance();
        config.addStrategy(StrategyType.EMPTY, (v) -> "");
        config.addStrategy(StrategyType.CHINESE_NAME, SensitiveDataUtils::chineseName);
        config.addStrategy(StrategyType.ID_CARD, SensitiveDataUtils::idCardNum);
        config.addStrategy(StrategyType.FIXED_PHONE, SensitiveDataUtils::fixedPhone);
        config.addStrategy(StrategyType.MOBILE_PHONE, SensitiveDataUtils::mobilePhone);
        config.addStrategy(StrategyType.EMAIL, SensitiveDataUtils::email);
        config.addStrategy(StrategyType.BANK_CARD, SensitiveDataUtils::bankCard);
        config.addStrategy(StrategyType.BANK_NUMBER, SensitiveDataUtils::bankNumber);
        config.addStrategy(StrategyType.RESERVE_4, (v) -> SensitiveDataUtils.setReserveSize(v, 4));
        config.addStrategy(StrategyType.RESERVE_6, (v) -> SensitiveDataUtils.setReserveSize(v, 6));
        config.addStrategy(StrategyType.RESERVE_8, (v) -> SensitiveDataUtils.setReserveSize(v, 8));
    }

    private SensitiveConfig() {
    }

    public static SensitiveConfig getInstance() {
        return instance;
    }

    /**
     * 添加策略
     * @param name 策略名称
     * @param processor 脱敏执行器
     */
    public SensitiveConfig addStrategy(String name, Function<String, Object> processor) {
        if (strategyMap.containsKey(name)) {
            log.warn("脱敏策略 [{}] 已存在, 将被覆盖", name);
        }
        if (processor == null) {
            log.warn("脱敏策略 [{}] 执行器为空, 添加无效", name);
            return this;
        }
        strategyMap.put(name, processor);
        return this;
    }

    public Function<String, Object> getStrategyProcessor(String name) {
        return strategyMap.get(name);
    }
}
